home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / evalx.com / EVALX.DOC < prev    next >
Encoding:
Text File  |  1990-09-17  |  18.5 KB  |  475 lines

  1.  
  2.  
  3.  
  4.      EVALX.DOC                 Monday, September 17, 1990                 Page 1
  5.  
  6.  
  7.       
  8.       
  9.       
  10.       
  11.       
  12.       
  13.       
  14.       
  15.       
  16.       
  17.       
  18.       
  19.       
  20.       
  21.       
  22.       
  23.       
  24.       
  25.       
  26.       
  27.                    +-----------------------------------+
  28.                    |                                   |
  29.                    |              evalx.c              |
  30.                    |                                   |
  31.                    +-----------------------------------+
  32.       
  33.                    Algebraic Expression Evaluator/Parser
  34.                         James P. Hawkins  - WA2WHV
  35.                               P.O. Box 9146,
  36.                              Trenton, NJ 08650
  37.                             September 11, 1990
  38.       
  39.       
  40.       
  41.       
  42.       
  43.       
  44.       
  45.       
  46.       
  47.       
  48.       
  49.       
  50.       
  51.       
  52.       
  53.       
  54.       
  55.       
  56.       
  57.       
  58.       
  59.       
  60.       
  61.       
  62.  
  63.  
  64.  
  65.      EVALX.DOC                 Monday, September 17, 1990                 Page 2
  66.  
  67.  
  68.       
  69.       
  70.       
  71.       
  72.       
  73.       
  74.       
  75.       
  76.       
  77.       
  78.       
  79.       
  80.       
  81.       
  82.      DESCRIPTION
  83.      _____________________________________________________________________
  84.       
  85.          Evalx  is  a convenient, powerful function which, when passed
  86.          an ASCII  string  representing  an  algebraic  expression  of
  87.          floating  point  numbers  and math functions, will return the
  88.          answer in a single floating point number.  The expression may
  89.          contain operators +, -, /, *, ^ and ().  Parens may be nested
  90.          more times than most would need.   Embedded  white  space  is
  91.          allowed.
  92.       
  93.          Example:  2.0 + 22 * (3.1415926  * (2.4 - 33) + 3.3 ^ 2)/43 +
  94.          (22 / 3.14)^3
  95.       
  96.          Also, functions are available and can be used as shown in the
  97.          following example:
  98.       
  99.          ((5.6 ^ 2 + sin(30 * (2 * 3.14159)/360)))
  100.       
  101.          which is 5.6  squared  plus  sin  of  30  degrees.   The  sin
  102.          function  uses  the angle in radians, so the conversion ratio
  103.          is included in the argument to the sin function.
  104.       
  105.      MATH FUNCTIONS
  106.      _____________________________________________________________________
  107.       
  108.          The expression may contain digits representing decimal numbers
  109.          or the following math functions:
  110.       
  111.                  sin(expstr) - sine of an angle in radians
  112.                  cos(expstr) - cosine of an angle in radians
  113.                  exp(expstr) - exponentiate
  114.                  log(expstr) - natural log
  115.                  int(expstr) - integerize (truncate to right of dec .)
  116.                  sqr(expstr) - square root
  117.                  abs(expstr) - absolute value
  118.                  atn(expstr) - arctan
  119.                  rnd(expstr) - random number gen
  120.                  tan(expstr) - tangent of an angle
  121.                  fact(expstr) - factorial
  122.       
  123.  
  124.  
  125.  
  126.      EVALX.DOC                 Monday, September 17, 1990                 Page 3
  127.  
  128.  
  129.       
  130.       
  131.       
  132.       
  133.       
  134.       
  135.       
  136.       
  137.       
  138.      CALLING FORMAT
  139.      _____________________________________________________________________
  140.       
  141.          A pointer to the string expression is passed to evalx() which
  142.          returns a resulting value  as  a  double  precision  floating
  143.          point number.
  144.       
  145.              double value;               /* declare a double */
  146.              double evalx(char *expstr); /* declare the function */
  147.       
  148.              value = evalx(expstr);      /* evaluate the expression and */
  149.                                          /* return it in value */
  150.       
  151.              where: expstr is the char string representing the expression
  152.                     to be evaluated. The string must be NULL terminated.
  153.       
  154.          To test for an error, simply do a switch(errorflg).  Errorflg
  155.          must  be declared as an extern int in the calling program.  A
  156.          zero value indicates no error, otherwise the error  condition
  157.          is defined as follows:
  158.       
  159.                  ERRFATAL -      FATAL ERROR
  160.                  ERRSYNTAX -     SYNTAX ERROR
  161.                  ERROVFLOW -     OVERFLOW ERROR
  162.                  ERRSQRT-        SQUARE ROOT OF NEG NUMBER ERROR
  163.                  ERRFACT -       FACTORIAL OF NEG or NUM > 33 ERROR
  164.                  ERRFUNC -       UNKNOWN FUNCTION ERROR
  165.                  ERRILLVAR -     ILLEGAL VARIABLE TYPE
  166.       
  167.       
  168.      EXAMPLE PROGRAM
  169.      _____________________________________________________________________
  170.       
  171.          The  following  is  a  program example of the use of evalx().
  172.          When compiled, it provides a  command  which  when  given  an
  173.          expression  as an argment (no embedded spaces) will print the
  174.          answer.  Or when invoked with no  argment,  will  prompt  for
  175.          expression  input.   Embedded space IS allowed when prompted.
  176.          The  parser  itself  handles  embedded  spaces,  however,  an
  177.          argument   to   a   command  with  embedded  spaces  will  be
  178.          interpreted by the command shell as multiple arguments unless
  179.          it  is  surrounded  by  quotes.   Also  note that in the UNIX
  180.          shell,  parens  must  be  "hidden"  from  the  shell  with  a
  181.          preceding '\'.
  182.       
  183.          #include        <stdio.h>
  184.  
  185.  
  186.  
  187.      EVALX.DOC                 Monday, September 17, 1990                 Page 4
  188.  
  189.  
  190.          #include        "evalx.h"  /* Must be included error constants */
  191.       
  192.          double evalx(char *ptr);   /* declare evalx() */
  193.       
  194.          extern  int     errorflg;  /* declare external errorflg */
  195.       
  196.          main(int argc, char **argv)
  197.          {
  198.                  double val;        /* declare double for result */
  199.                  int     exitflg = 0;
  200.                  char    str[80];   /* storage for expression string */
  201.       
  202.                  while(1)
  203.                  {
  204.                          /*
  205.                           * If expression was in command argument then
  206.                           * Compute, print, then quit.
  207.                           * Else, wait for an input to be typed, compute,
  208.                           * print, then wait again.
  209.                           */
  210.                          if(argc > 1)
  211.                          {
  212.                                  strcpy(str, argv[1]);
  213.                                  exitflg++;
  214.                          }
  215.                          else
  216.                          {
  217.                                  printf("Input Expression:\n");
  218.                                  gets(str);
  219.                          }
  220.                          val = evalx(str); /* Evaluate the expression */
  221.       
  222.                          /* Test error condition if any */
  223.                          switch(errorflg)
  224.                          {
  225.                          case 0: /* NO ERROR, PRINT RESULT */
  226.                                  printf("Result=%g\n", val);
  227.                                  if(exitflg)
  228.                                  {
  229.                                          exit(0);
  230.                                  }
  231.                                  break;
  232.                          case    ERRFATAL:
  233.                                  printf("Fatal error\n");
  234.                                  break;
  235.                          case    ERRSYNTAX:
  236.                                  printf("Syntax error\n");
  237.                                  break;
  238.                          case    ERROVFLOW:
  239.                                  printf("Overflow error\n");
  240.                                  break;
  241.                          case    ERRSQRT:
  242.                                  printf("Square root of neg number error\n");
  243.                                  break;
  244.                          case    ERRFACT:
  245.  
  246.  
  247.  
  248.      EVALX.DOC                 Monday, September 17, 1990                 Page 5
  249.  
  250.  
  251.                                  printf("Factorial error\n");
  252.                                  break;
  253.                          case    ERRFUNC:
  254.                                  printf("Unknown math function error\n");
  255.                                  break;
  256.                          case    ERRILLVAR:
  257.                                  printf("Illegal variable error\n");
  258.                                  break;
  259.                          default:
  260.                                  break;
  261.                          }
  262.                  }
  263.          }
  264.       
  265.      ALGORITHM
  266.      _____________________________________________________________________
  267.       
  268.          The   evalx()  function  loops  until  a  null  character  is
  269.          encountered.
  270.       
  271.          t the beginning of each loop, the function class() is called.
  272.          This is in the file class.c which MUST be compiled and linked
  273.          with evalx.c and the program.  Class() classifies  each  item
  274.          as  a  field of type OPCLASS, NMCLASS or FNCLASS.  OPCLASS is
  275.          returned  if,  an  operator  +,-,/,*,^,(,)  is   encountered.
  276.          NMCLASS  is  returned  if  a number is scanned and FNCLASS is
  277.          returned if  the  field  is  a  function  containing  another
  278.          expression  such  as  sin(22  +  33).   The  class  of  field
  279.          determines what action, evalx is to take next.
  280.       
  281.          There are two stacks, one  for  numbers  or  operands  called
  282.          double  opndstack[]  and  one  for  operators char opstack[].
  283.          When a number is encountered in the string it is converted to
  284.          a  double  precision  floating point number and simply pushed
  285.          onto the operand stack.  When an operator, other than parens,
  286.          is encountered, the stackop() function is called.
  287.       
  288.          Stackop() uses precedence rules to determine what to do  with
  289.          the  current  operator.   The  precedence  of  an operator is
  290.          computed by passing the operator to  the  preced()  function.
  291.          The  preced  function  returns a value of 1 for the operators
  292.          '+' and '-', 2 for '*' and '/'  and  finally  3  for  '^'  or
  293.          exponentiate.   The  precedence  of  the  current operator is
  294.          compared with the precedence of the operator on  the  top  of
  295.          the  stack.  If precedence of current operator is higher than
  296.          the operator on top of the stack or  the  operator  stack  is
  297.          empty,  the  precedence  test  has  "passed" so just push the
  298.          current operator onto the operator  stack.   If  the  current
  299.          operator  precedence is less than or equal to the operator on
  300.          the top of the stack, the topmost operator is applied to  the
  301.          two  topmost  two  operands in the operand stack by a call to
  302.          unstack().  Unstack() is called until  either  the  stack  is
  303.          empty  or  the  precedence  test  passes in which the current
  304.          operator is finally placed on the operator stack.   That  is,
  305.          the  unstack() function does the actual arithmetic operations
  306.  
  307.  
  308.  
  309.      EVALX.DOC                 Monday, September 17, 1990                 Page 6
  310.  
  311.  
  312.          in evalx().  Examination of the unstack() function will  show
  313.          that  it  contains a simple switch() statement which uses the
  314.          operator to determine which operation is to be  performed  on
  315.          the  topmost  operands.  Then, the operator and operand stcks
  316.          are popped.
  317.       
  318.          When an open parenthesis '(' operator is encountered, evalx()
  319.          is  recursively  called  to  evaluate whatever is inside of a
  320.          pair  of  balanced  parenthesis.   When  a  close  paren  ')'
  321.          operator  is  encountered,  the  cleanup() function is called
  322.          which simply cleans up both stacks  by  doing  all  remaining
  323.          calculations.   Then  evalx()  returns  to  either  a  higher
  324.          instance of evalx() or the original calling function.   Since
  325.          the  operator opstack[] and the operand stack opndstack[] are
  326.          automatic variables, the stack size need only be as large  as
  327.          there  are precedence values, because each instance of nested
  328.          parens results in another  call  to  evalx(),  which  creates
  329.          another  instance  of  these small stacks.  Each time evalx()
  330.          returns,  that  instance  of  stacks  is  no  longer  needed.
  331.          Remember  that  automatic generation is implicitly handled by
  332.          stack management.  Throughout the  evaluation,  eoexpr  is  a
  333.          global  string  place  holder.  This probably could have been
  334.          handled with automatic variables also.   When  the  first  or
  335.          highest  instance  of  evalx()  is  finished  when the end of
  336.          string is encountered, a final cleanup() is done to  evaluate
  337.          whatever is left on the operand stack.
  338.       
  339.          If the class() function  encounters  a  function,  it  copies
  340.          everything  within  balanced  parenthesis of the function and
  341.          places it in the field[] array.  Then  mathcall()  is  called
  342.          with  this  string  passed  to  it.  Mathcall() does a string
  343.          search for the math function in a  table  which  consists  of
  344.          name, function address pairs.  If the function, such as "sin"
  345.          is encountered, the string value that is passed to mathcall()
  346.          is  evaluated  by  a call to evalx() (another recursion), and
  347.          the returned number is passed to  the  appropriate  function.
  348.          The return value of the function is returned by mathcall() to
  349.          the calling instance of evalx() which is put on the  operator
  350.          or  operand  stack  and treated like any other number for the
  351.          rest  of  the  evaluation  within  the   current   level   of
  352.          parenthesis.    If  a  function  field  is  encountered,  the
  353.          mathcall() function is called.
  354.       
  355.          The operation of the class function is left  as  an  exersize
  356.          for the reader!
  357.       
  358.      COMPILATION WITH EXAMPLE PROGRAM
  359.      _____________________________________________________________________
  360.       
  361.          Included in this package are the following files:
  362.       
  363.              calc.c      - Example calling program
  364.              evalx.c     - Evaluator.
  365.              class.c     - Expression field classifier.
  366.              evalx.h     - Header for evalx.c and class.c
  367.  
  368.  
  369.  
  370.      EVALX.DOC                 Monday, September 17, 1990                 Page 7
  371.  
  372.  
  373.                            This must be #included in calling program!
  374.              calc.mak    - Makefile for Microsoft 5.1 make
  375.              evalx.doc   - This document
  376.              calc.exe    - Example program compiled.  Try it!
  377.       
  378.          This program was compiled using Microsoft C 5.1.  If you have
  379.          Microsoft C 5.1 use make as follows.
  380.       
  381.              make calc.mak calc.exe
  382.       
  383.          However you compile the program, class.c must also be  linked
  384.          in.   Also,  the calling program must have #include "evalx.h"
  385.          and a declaration extern int errorflg.
  386.       
  387.      IMPORTANT NOTICE!
  388.      _____________________________________________________________________
  389.       
  390.          This  software  is  free,  however I would appreciate a small
  391.          donation of $5.00 if you find it useful, or whatever you wish
  392.          to help support my continued efforts in providing more useful
  393.          software.  Please send to address below.  Thankyou!  You  may
  394.          distribute this software by any means, but you may NOT charge
  395.          for this software by itself,  except  to  cover  distribution
  396.          costs.  You may use it in software you develop and charge for
  397.          your software.  Unless drastically  altered,  please  do  not
  398.          remove   my   name   as   author   from  the  software.   All
  399.          documentation and files must be included.
  400.       
  401.          WARRANTEE: This program is being provided "AS IS". It  is  up
  402.          to  the user to determine the suitability of this program for
  403.          their purposes. The user takes  all  responsibility  for  any
  404.          direct or consequential damages.
  405.       
  406.      _____________________________________________________________________
  407.       
  408.          James P. Hawkins - WA2WHV
  409.          P.O. Box 9146
  410.          Trenton, NJ 08650
  411.       
  412.          CompuServe 76446,613
  413.       
  414.       
  415.       
  416.       
  417.       
  418.       
  419.       
  420.       
  421.       
  422.       
  423.       
  424.       
  425.       
  426.       
  427.  
  428.  
  429.          ----------------end-of-author's-documentation---------------
  430.  
  431.                          Software Library Information:
  432.  
  433.                     This disk copy provided as a service of
  434.  
  435.                            Public (software) Library
  436.  
  437.          We are not the authors of this program, nor are we associated
  438.          with the author in any way other than as a distributor of the
  439.          program in accordance with the author's terms of distribution.
  440.  
  441.          Please direct shareware payments and specific questions about
  442.          this program to the author of the program, whose name appears
  443.          elsewhere in  this documentation. If you have trouble getting
  444.          in touch with the author,  we will do whatever we can to help
  445.          you with your questions. All programs have been tested and do
  446.          run.  To report problems,  please use the form that is in the
  447.          file PROBLEM.DOC on many of our disks or in other written for-
  448.          mat with screen printouts, if possible.  PsL cannot debug pro-
  449.          programs over the telephone, though we can answer questions.
  450.  
  451.          Disks in the PsL are updated  monthly,  so if you did not get
  452.          this disk directly from the PsL, you should be aware that the
  453.          files in this set may no longer be the current versions. Also,
  454.          if you got this disk from another vendor and are having prob-
  455.          lems,  be aware that  some files may have become corrupted or
  456.          lost by that vendor. Get a current, working disk from PsL.
  457.  
  458.          For a copy of the latest monthly software library newsletter
  459.          and a list of the 2,000+ disks in the library, call or write
  460.  
  461.                            Public (software) Library
  462.                                P.O.Box 35705 - F
  463.                             Houston, TX 77235-5705
  464.  
  465.                                 1-800-2424-PSL
  466.                                  MC/Visa/AmEx
  467.  
  468.                           Outside of U.S. or in Texas
  469.                           or for general information,
  470.                               Call 1-713-524-6394
  471.  
  472.                           PsL also has an outstanding
  473.                           catalog for the Macintosh.
  474.  
  475.